import {find_player} from "../player/player_class"

type batType = {
    name:string,
    mesh:GameModelAssets,
    speed:number,
    health:number
}
const batType:batType[] = [
    {
        name:'自爆蝙蝠',
        mesh:'mesh/蝙蝠-1.vb',
        speed:0.5,
        health:10,
    },
]

const bats:[number,bat][] = []

class bat{
    
    entity:GameEntity
    use:boolean = true
    type:number
    can_bomb:boolean = true

    constructor(pos:GameVector3,type:number)
    {
        this.type = type
        this.entity = world.createEntity({
            mesh:batType[type].mesh,
            meshScale:new GameVector3(1/16,1/16,1/16),
            position:pos,

            collides:true,
            fixed:false,
            gravity:false,
            tags:['bat']
        })!

        this.entity.enableDamage = true
        this.entity.hp = batType[type].health
        this.entity.maxHp = batType[type].health

        if(batType[type].name == '自爆蝙蝠')
        {
            this.entity.friction = 1
            async function bomb(t:bat)
            {
                if(!t.can_bomb)
                    return
                else
                    t.can_bomb = false

                t.entity.sound('audio/explode.mp3')
                const len = 3
                for(const e of find_player<GameBounds3>('Gamebound3',new GameBounds3(
                    t.entity.position.sub(new GameVector3(len,len,len)),
                    t.entity.position.add(new GameVector3(len,len,len)),
                )))
                {
                    if(e.data.hp > 0)
                        e.hurt(30,'bomb')
                }

                setTimeout(() => {
                    t.entity.hurt(1000)
                },3000)
            }
            
            this.entity.onVoxelContact(() => {
                bomb(this)
            })
            this.entity.onEntityContact(() => {
                bomb(this)
            })
        }

        this.entity.onDie(() => {
            this.entity.velocity.set(0,0,0)

            this.entity.hp = this.entity.maxHp
            const ran = Math.random()*Math.PI*2

            this.entity.position = new GameVector3(
                128-Math.sin(ran)*70,
                80,
                128-Math.cos(ran)*70
            )
            
            this.can_bomb = true
        })

        bats.push([type,this])
    }

    create(pos:GameVector3)
    {
        this.use = true
        this.entity.position = pos
        this.entity.fixed = false
    }
}


world.onTick(({tick}) => {
    //get player
    const players = find_player<GameBounds3>('Gamebound3',new GameBounds3(new GameVector3(0,0,0),voxels.shape))
    //
    for(const ef of bats)
    {
        if(!ef[1].use || ef[1].entity.hp <= 0)
            return
        const e = ef[1]

        if(batType[e.type].name == '自爆蝙蝠')
        {
            let es:GameEntity|null = null,len = 1000
            for(const p of players)
            {
                if(p.data.hp > 0 && mhd(p.data.position,e.entity.position) < len)
                {
                    es = p.data.entitys.bound
                    len = mhd(p.data.position,e.entity.position)
                }
            }

            if(es)
            {
                const v = es.position.sub(e.entity.position).normalize()
                const r = world.raycast(e.entity.position,v,{
                    ignoreSelector:'.bat'
                })
                if(r.hitEntity && r.hitEntity.id == 'player')
                {
                    e.entity.velocity = v.scale(batType[e.type].speed)
                    e.entity.lookAt(es.position)
                }    
                else
                {
                    const ran = Math.random()*Math.PI*2
                    e.entity.velocity.set(
                        Math.sin(ran)*batType[e.type].speed,
                        Math.random(),
                        Math.cos(ran)*batType[e.type].speed
                    )
                }
            }
            else
            {
                const v = new GameVector3(128,30,128).sub(e.entity.position).normalize()
                e.entity.velocity = v.scale(batType[e.type].speed)
                e.entity.lookAt(new GameVector3(128,30,128))
            }
        }
    }
})

function mhd(a:GameVector3,b:GameVector3)
{
    return Math.abs(a.x-b.x)+Math.abs(a.z-b.z)+Math.abs(a.y-b.y)
}

export function createBat(pos:GameVector3,type:number)
{
    for(const e of bats)
    {
        if(e[0] == type && !e[1].use)
        {
            e[1].create(pos)
            return
        }
    }
    new bat(pos,type)
}